cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
# project name
project(tiec)

# Compiler special
if (MSVC)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:__cplusplus")
endif ()

# macro
option(ENABLE_LOG "Enable logging" ON)
option(STATIC_LIB "Build static lib not dynamic" OFF)
option(BUILD_PC_DEMO "Build demo for Windows/Mac/Linux to test" ON)
option(WEB "Merge web platform source to project" OFF)

# initial config
set(LINK_LIB)
set(CMAKE_PROJECT_DIR ${CMAKE_SOURCE_DIR})
set(SRC_DIR ${CMAKE_PROJECT_DIR}/src)
set(3DPARTY_DIR ${CMAKE_PROJECT_DIR}/3dparty)

# header search path
include_directories(${SRC_DIR})
include_directories(${SRC_DIR}/include)
include_directories(${SRC_DIR}/core)
include_directories(${SRC_DIR}/util)
include_directories(${3DPARTY_DIR}/reflex/include)
if (ENABLE_LOG)
    include_directories(${3DPARTY_DIR}/logger)
    add_definitions(-DENABLE_LOG)
endif ()

# core source files config
file(GLOB_RECURSE CORE_SOURCE_FILES
        ${SRC_DIR}/include/*.*
        ${SRC_DIR}/core/*.*
        ${SRC_DIR}/util/*.*
        )
if (ENABLE_LOG)
    message(STATUS "Log enabled")
    file(GLOB_RECURSE LOGGER_FILES ${3DPARTY_DIR}/logger/*.*)
    set(CORE_SOURCE_FILES ${CORE_SOURCE_FILES} ${LOGGER_FILES})
endif ()

# Determine whether to build a demo and which platform to build demo on
if (BUILD_PC_DEMO AND NOT ANDROID AND NOT IOS AND NOT HARMONY)
    set(DEMO_NAME TiecodeCompilerDemo)

    if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
        add_definitions(-DMACOS)
        set(MACOS ON)
        set(BUILD_DEMO_MACOS ON)
    elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
        add_definitions(-DWINDOWS -D_POSIX -D_POSIX_THREAD_SAFE_FUNCTIONS)
        set(WINDOWS ON)
        set(BUILD_DEMO_WINDOWS ON)
    elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
        add_definitions(-DLINUX)
        add_definitions(-DFORCE_GLFW)
        set(LINUX ON)
        set(BUILD_DEMO_LINUX ON)
    endif ()
endif ()

# Platform special
if (ANDROID)
    file(GLOB_RECURSE PLATFORM_FILES ${SRC_DIR}/platform/android/*.*)
elseif (IOS)
    file(GLOB_RECURSE PLATFORM_FILES ${SRC_DIR}/platform/ios/*.*)
elseif (HARMONY)
    file(GLOB_RECURSE PLATFORM_FILES ${SRC_DIR}/platform/harmony/*.*)
elseif (WINDOWS)
    file(GLOB_RECURSE PLATFORM_FILES ${SRC_DIR}/platform/windows/*.*)
elseif (MACOS)
    file(GLOB_RECURSE PLATFORM_FILES ${SRC_DIR}/platform/osx/*.*)
elseif (LINUX)
    file(GLOB_RECURSE PLATFORM_FILES ${SRC_DIR}/platform/linux/*.*)
endif ()
if (WEB)
    #include_directories(/opt/homebrew/Cellar/emscripten/3.1.54/libexec/system/include)
    file(GLOB_RECURSE WEB_PLATFORM_FILES ${SRC_DIR}/platform/web/*.*)
    set(PLATFORM_FILES ${PLATFORM_FILES} ${WEB_PLATFORM_FILES})
endif ()

# project shared/dynamic lib
if (STATIC_LIB)
    add_library(${CMAKE_PROJECT_NAME} STATIC ${CORE_SOURCE_FILES} ${PLATFORM_FILES})
else ()
    add_library(${CMAKE_PROJECT_NAME} SHARED ${CORE_SOURCE_FILES} ${PLATFORM_FILES})
endif ()

# add library functions
function(android_add_3dparty_shared_lib dir name)
    add_library(${name} SHARED IMPORTED)
    set_target_properties(${name}
            PROPERTIES IMPORTED_LOCATION
            ${3DPARTY_DIR}/${dir}/android/${CMAKE_ANDROID_ARCH_ABI}/lib${name}.so)
    set(LINK_LIB ${LINK_LIB} ${name} PARENT_SCOPE)
endfunction()
function(ios_add_3dparty_static_lib dir name)
    add_library(${name} STATIC IMPORTED)
    set_target_properties(${name}
            PROPERTIES IMPORTED_LOCATION
            ${3DPARTY_DIR}/${dir}/ios/arm64/lib${name}.a)
    set(LINK_LIB ${LINK_LIB} ${name} PARENT_SCOPE)
endfunction()
function(harmony_add_3dparty_static_lib dir name)
    add_library(${name} STATIC IMPORTED)
    set_target_properties(${name}
            PROPERTIES IMPORTED_LOCATION
            ${3DPARTY_DIR}/${dir}/harmony/arm64/lib${name}.a)
    set(LINK_LIB ${LINK_LIB} ${name} PARENT_SCOPE)
endfunction()
function(windows_add_3dparty_static_lib dir name)
    add_library(${name} STATIC IMPORTED)
    set_target_properties(${name}
            PROPERTIES IMPORTED_LOCATION
            ${3DPARTY_DIR}/${dir}/windows/lib${name}.a)
    set(LINK_LIB ${LINK_LIB} ${name} PARENT_SCOPE)
endfunction()
function(mac_add_3dparty_shared_lib dir name)
    add_library(${name} SHARED IMPORTED)
    set_target_properties(${name}
            PROPERTIES IMPORTED_LOCATION
            ${3DPARTY_DIR}/${dir}/osx/lib${name}.dylib)
    set(LINK_LIB ${LINK_LIB} ${name} PARENT_SCOPE)
endfunction()
function(linux_add_3dparty_static_lib dir name)
    add_library(${name} STATIC IMPORTED)
    set_target_properties(${name}
            PROPERTIES IMPORTED_LOCATION
            ${3DPARTY_DIR}/${dir}/linux/x86_64/lib${name}.a)
    set(LINK_LIB ${LINK_LIB} ${name} PARENT_SCOPE)
endfunction()


# add library
if (ANDROID)
    android_add_3dparty_shared_lib(reflex reflex_shared_lib)
    find_library(ANDROID_LIB android)
    find_library(LOG_LIB log)
    set(LINK_LIB ${LINK_LIB} ${ANDROID_LIB} ${LOG_LIB}
            )
elseif (IOS)
    find_library(FOUNDATION_FRAMEWORK Foundation)
    find_library(CORE_FOUNDATION_FRAMEWORK CoreFoundation)
    find_library(IOKIT_FRAMEWORK IOKit)
    find_library(QUARTZ_CORE_FRAMEWORK QuartzCore)
    find_library(UIKIT_FRAMEWORK UIKit)
    set(LINK_LIB ${LINK_LIB}
            ${FOUNDATION_FRAMEWORK} ${CORE_FOUNDATION_FRAMEWORK} ${IOKIT_FRAMEWORK}
            ${QUARTZ_CORE_FRAMEWORK} ${UIKIT_FRAMEWORK}
            )
elseif (HARMONY)

elseif (WINDOWS)
    windows_add_3dparty_static_lib(reflex reflex_static_lib)
elseif (MACOS)
    mac_add_3dparty_shared_lib(reflex reflex_shared_lib)
    find_library(FOUNDATION_FRAMEWORK Foundation)
    find_library(CORE_FOUNDATION_FRAMEWORK CoreFoundation)
    find_library(IOKIT_FRAMEWORK IOKit)
    find_library(QUARTZ_CORE_FRAMEWORK QuartzCore)
    find_library(APPKIT_FRAMEWORK AppKit)
    find_library(SECURITY_FRAMEWORK Security)
    set(LINK_LIB ${LINK_LIB}
            ${FOUNDATION_FRAMEWORK} ${CORE_FOUNDATION_FRAMEWORK} ${IOKIT_FRAMEWORK}
            ${QUARTZ_CORE_FRAMEWORK} ${APPKIT_FRAMEWORK} ${SECURITY_FRAMEWORK}
            )
elseif (LINUX)

endif ()

target_link_libraries(${CMAKE_PROJECT_NAME} ${LINK_LIB})

# Build demo executable for pc
if (BUILD_DEMO_WINDOWS)
    message(STATUS "Build Windows demo enabled")
    add_executable(${DEMO_NAME} WIN32
            ${CMAKE_SOURCE_DIR}/platform/Windows/demo/main.cpp
            ${CORE_SOURCE_FILES} ${PLATFORM_FILES}
            )
    target_link_libraries(${DEMO_NAME}
            ${LINK_LIB}
            )
elseif (BUILD_DEMO_MACOS)
    message(STATUS "Build MacOSX demo enabled")
    add_executable(${DEMO_NAME} MACOSX_BUNDLE
            ${CMAKE_SOURCE_DIR}/platform/OSX/demo/main.mm
            ${CORE_SOURCE_FILES} ${PLATFORM_FILES}
            )
    find_library(COCOA_FRAMEWORK Cocoa)
    find_library(METAL_FRAMEWORK Metal)
    find_library(QUARTZ_CORE_FRAMEWORK QuartzCore)
    find_library(IOKIT_FRAMEWORK IOKit)
    find_library(CORE_FOUNDATION_FRAMEWORK CoreFoundation)
    find_library(FOUNDATION_FRAMEWORK Foundation)
    find_library(APPKIT_FRAMEWORK AppKit)
    target_link_libraries(${DEMO_NAME}
            ${LINK_LIB}
            ${COCOA_FRAMEWORK}
            ${METAL_FRAMEWORK}
            ${QUARTZ_CORE_FRAMEWORK}
            ${IOKIT_FRAMEWORK}
            ${CORE_FOUNDATION_FRAMEWORK}
            ${FOUNDATION_FRAMEWORK}
            ${APPKIT_FRAMEWORK}
            )
elseif (BUILD_DEMO_LINUX)
    message(STATUS "Build Linux demo enabled")
    add_executable(${DEMO_NAME}
            ${CMAKE_SOURCE_DIR}/platform/Linux/demo/main.cpp
            ${CORE_SOURCE_FILES} ${PLATFORM_FILES}
            )
    target_link_libraries(${DEMO_NAME}
            ${LINK_LIB}
            )
endif ()
